#ifndef PATCHSRV_H
#define PATCHSRV_H

// luke 4/1/02: Timeouts used in determining when to close connections
#define KEEPALIVE_TIMEOUT	30000		// 1h  (ms)
#define KEEPALIVE_INTERVAL	1000		// 30s (ms)
#define STALE_TIMEOUT		10800000	// 3h  (ms)

#include "srviface.h"

#include <excpt.h>
#include <DbgHelp.h>

class PortIO;
class PackageList;
class Client;
class ReadersWriters;
class Admin;
class Timer;

class PatchServer : public ServerInterface
{
	public:
		PatchServer(int32 Port);
		~PatchServer();

		bool8 initSuccess();
		void run();
		void stop();

		PortIO* getPortIO();

		PackageList*	getPackageList();		// read-only access
		void			releasePackageList();

		PackageList*	lockPackageList();		// read/write access
		void			unlockPackageList();

        uint32          getPkgListChangeCount();

		bool8 isCorrectRemoteUpdateHost(const String& remoteip);
		bool8 isCorrectLogin(const String& username, const String& password);

		bool8	addTimer(long milisecs, Client* client);

		void    close(Client*);

		static uint32 __stdcall cleanUpThread(PatchServer* This);
		static uint32 __stdcall mrtgThread(PatchServer* This);
        static uint32 __stdcall packageWatchThread(PatchServer* This);  // kharmon.  08-03-06.  This thread waits for new packages to become available and then loads them into the system.

		void		addBytesIn(uint32 bytes);
		void		addBytesOut(uint32 bytes);

	protected:
		bool8	startListening();
		void	stopListening();

		void 	add(Client*);

		void    cleanUpClosedClients();

		bool8	allStale(uint32);

        // kharmon.  08-03-06.  Methods for starting and stoping the 
        // new package upload process.
        void    createNewPackageWatch();
        void    startNewPackageWatch();
        void    stopNewPackageWatch();
        void    resetNewPackageWatch();
        void    destroyNewPackageWatch(); 

		int CreateMiniDump( EXCEPTION_POINTERS* pep );	// CSN-6738. Remove when investigation finishes
		Client* NewClient(SOCKET c);					// CSN-6738. Remove when investigation finishes
		

	public:
		static PatchServer* This;		// only one instanciated

	protected:
		SOCKET				server;
		HANDLE				stopEvt;
		HANDLE				sockEvt;
		HANDLE				cleanClientsThread;
		HANDLE				hmrtgThread;
		Timer*				timer;
		bool8				sockinit;
		bool8				stopping;
		uint16				dummy;		// alignment
		uint64				bytesIn;
		uint64				bytesOut;
		uint32				timestarted;

		PortIO*				portio;

		PackageList*		pkgs;
		ReadersWriters*		pkgRW;

		PCRITICAL_SECTION	cliMutex;
		PCRITICAL_SECTION	cliTransIn;
		PCRITICAL_SECTION	cliTransOut;
		Client*				clients;
		int32				numClients;

		Admin*				admin;

        HANDLE              m_hNewPkgDir;           // kharmon.  08-01-06.  Handle to directory to watch for new package files.
        HANDLE              m_hPkgDirEvent;         // Event that triggers when a new file is added to the "NewPackage" directory
        HANDLE				m_hPackageWatchThread;  // Handle to the thread that loads the new packages
        HANDLE              m_hNewPkgTrigger;       // handle for IO completion port that triggers the actual "upload" process.
        OVERLAPPED *        m_pPkgOverlap;          // pointer to the overlapped structure that the OS will fill out when the next NewPackage directory change occurs.

        // key types used with the ioocompletion port stuff to send messages to the watch thread.
        enum NewPackageKeyTypes
        {
            NEW_PKG_STARTUP=0,
            NEW_PKG_FILE,
            NEW_PKG_SHUTDOWN
        };

        const static int32  FILE_NAME_INFO_BUFFER_SIZE = 4096; 

       
};

inline PortIO*
PatchServer::getPortIO()
{
	return portio;
}

#endif
